pub mod rpc_server {
    tonic::include_proto!("config_monitor_s");
}
use std::{collections::HashMap, sync::Arc};

use tonic::{Request, Response, Status};

use crate::agent::{rpc_client, Agent};
use crate::label_manager::LabelManager;

/// rpc调用绑定在这个结构体上，实现了trait
///
/// Myserver.run()方法中启动了rpc_server，创建了一个impl实例对象，rpc函数中需要操作MyServer的repo和agents字段
///
/// 需要将MyServer的repo和agents字段传入RpcServerimpl中。
pub struct RpcServerimpl {
    /// git仓库在server节点中的路径前缀
    repo_path: String,
    agents: Arc<tokio::sync::Mutex<Box<HashMap<String, Agent>>>>,
    /// 标签管理器
    label_manager: Arc<tokio::sync::Mutex<LabelManager>>,
}

impl RpcServerimpl {
    pub fn new(
        repo_path: String,
        agents: Arc<tokio::sync::Mutex<Box<HashMap<String, Agent>>>>,
    ) -> Self {
        RpcServerimpl { 
            repo_path, 
            agents,
            label_manager: Arc::new(tokio::sync::Mutex::new(LabelManager::new())),
        }
    }
}

#[tonic::async_trait]
impl rpc_server::config_monitor_s_server::ConfigMonitorS for RpcServerimpl {
    async fn register_agent(
        &self,
        request: Request<rpc_server::RegisterAgentRequest>,
    ) -> Result<Response<rpc_server::RegisterAgentResponse>, Status> {
        let req = request.into_inner();
        let agent_info = req.agent_info.ok_or_else(|| {
            Status::invalid_argument("Agent info is required")
        })?;

        println!("*** Agent注册: ID={}, 地址={}", agent_info.agent_id, agent_info.agent_address);
        println!("*** Agent标签: {:?}", agent_info.labels);

        let agent_address = agent_info.agent_address.clone();
        let agent = Agent::new(agent_address.clone());

        // 向这个agent初始化文件
        match agent.init_files(self.repo_path.clone()).await {
            Ok(_) => {
                // 将agent加入到agents中
                self.agents.lock().await.insert(agent_address, agent);
                
                // 注册到标签管理器并获取自动分配的组
                let assigned_groups = self.label_manager.lock().await.register_agent(agent_info);
                
                println!("*** Agent自动分配到组: {:?}", assigned_groups);
                
                let reply = rpc_server::RegisterAgentResponse {
                    success: true,
                    message: "Agent registered successfully with label support".to_string(),
                    assigned_groups,
                };
                Ok(Response::new(reply))
            }
            Err(e) => {
                eprintln!("初始化Agent文件失败: {:?}", e);
                let reply = rpc_server::RegisterAgentResponse {
                    success: false,
                    message: format!("Agent registration failed: {}", e),
                    assigned_groups: vec![],
                };
                Ok(Response::new(reply))
            }
        }
    }

    /// agent上报异常
    async fn report_exception(
        &self,
        request: Request<rpc_server::ReportExceptionRequest>,
    ) -> Result<Response<rpc_server::ReportExceptionResponse>, Status> {
        #[cfg(debug_assertions)]
        println!("!!!Got a rpc report_exception request: {:?}", request);

        let agent_address = request.get_ref().agent_address.clone();
        let exception = request.get_ref().exception_message.clone();

        //解析出exception的文件路径 形如key=\"CM_{file_path}，截止到第一个"
        #[cfg(debug_assertions)]
        println!("exception: {}", exception);

        println!("{}", Self::parse_audit_log(&request));

        let file_path = exception
            .split("key=\"CM_")
            .collect::<Vec<&str>>()
            .get(1)
            .unwrap()
            .split("\"")
            .collect::<Vec<&str>>()
            .get(0)
            .unwrap()
            .to_string();

        let reply = rpc_server::ReportExceptionResponse {
            success: true,
            message: format!("Agent {} reported exception: {}", agent_address, exception),
        };

        // sync_config_file
        rpc_client::config_monitor_a_client::ConfigMonitorAClient::connect(
            "http://".to_owned() + &agent_address.clone(),
        )
        .await
        .unwrap()
        .sync_config(tonic::Request::new(rpc_client::SyncConfigRequest {
            config_file_path_agent: file_path.clone(),
            config_file_content: std::fs::read_to_string(self.repo_path.clone() + &file_path)
                .unwrap(),
            action: rpc_client::ConfigFileAction::Sync as i32,
        }))
        .await
        .unwrap();

        Ok(Response::new(reply))
    }

    /// 按标签组发送配置
    async fn send_config_to_label_group(
        &self,
        request: Request<rpc_server::SendConfigToLabelGroupRequest>,
    ) -> Result<Response<rpc_server::SendConfigToLabelGroupResponse>, Status> {
        let req = request.into_inner();
        let selector = req.selector.ok_or_else(|| {
            Status::invalid_argument("Label selector is required")
        })?;

        println!("收到标签组配置下发请求: {:?}", selector.match_labels);

        // 匹配符合条件的Agent
        let matched_agents = self.label_manager.lock().await.match_agents(&selector);
        println!("标签选择器匹配到 {} 个Agent: {:?}", matched_agents.len(), matched_agents);

        let mut affected_agents = Vec::new();
        let mut success_count = 0;

        // 向匹配的Agent发送配置
        for agent_id in &matched_agents {
            if let Some(agent_info) = self.label_manager.lock().await.get_agent(agent_id) {
                let agent_address = agent_info.agent_address.clone();
                
                match self.send_config_to_agent(&agent_address, &req.config_content, &req.config_path).await {
                    Ok(_) => {
                        success_count += 1;
                        affected_agents.push(agent_id.clone());
                        println!("成功向Agent {} 发送配置", agent_id);
                    }
                    Err(e) => {
                        eprintln!("向Agent {} 发送配置失败: {}", agent_id, e);
                    }
                }
            }
        }

        Ok(Response::new(rpc_server::SendConfigToLabelGroupResponse {
            success: success_count == matched_agents.len(),
            affected_agents,
            message: format!("成功发送到 {}/{} 个Agent", success_count, matched_agents.len()),
        }))
    }

    /// 按标签组执行命令
    async fn execute_command_on_label_group(
        &self,
        request: Request<rpc_server::ExecuteCommandOnLabelGroupRequest>,
    ) -> Result<Response<rpc_server::ExecuteCommandOnLabelGroupResponse>, Status> {
        let req = request.into_inner();
        let selector = req.selector.ok_or_else(|| {
            Status::invalid_argument("Label selector is required")
        })?;

        println!("收到标签组命令执行请求: 命令={}, 选择器={:?}", req.command, selector.match_labels);

        // 匹配符合条件的Agent
        let matched_agents = self.label_manager.lock().await.match_agents(&selector);
        println!("标签选择器匹配到 {} 个Agent", matched_agents.len());

        let mut results = Vec::new();

        // 向匹配的Agent执行命令
        for agent_id in matched_agents {
            if let Some(agent_info) = self.label_manager.lock().await.get_agent(&agent_id) {
                let agent_address = agent_info.agent_address.clone();
                
                match self.execute_command_on_agent(&agent_address, &req.command).await {
                    Ok(output) => {
                        results.push(format!("{}: {}", agent_id, output));
                        println!("Agent {} 命令执行成功", agent_id);
                    }
                    Err(e) => {
                        results.push(format!("{}: ERROR - {}", agent_id, e));
                        eprintln!("Agent {} 命令执行失败: {}", agent_id, e);
                    }
                }
            }
        }

        let result_count = results.len();
        Ok(Response::new(rpc_server::ExecuteCommandOnLabelGroupResponse {
            success: true,
            results,
            message: format!("命令执行完成，共处理 {} 个Agent", result_count),
        }))
    }

    /// 获取标签组信息
    async fn get_label_groups(
        &self,
        _request: Request<rpc_server::GetLabelGroupsRequest>,
    ) -> Result<Response<rpc_server::GetLabelGroupsResponse>, Status> {
        let groups = self.label_manager.lock().await.get_all_groups()
            .into_iter()
            .cloned()
            .collect();

        Ok(Response::new(rpc_server::GetLabelGroupsResponse {
            groups,
        }))
    }
}
impl RpcServerimpl {
    /// 向单个Agent发送配置
    async fn send_config_to_agent(
        &self,
        agent_address: &str,
        config_content: &str,
        config_path: &str,
    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let mut client = rpc_client::config_monitor_a_client::ConfigMonitorAClient::connect(
            format!("http://{}", agent_address)
        ).await?;

        let request = rpc_client::SyncConfigRequest {
            config_file_path_agent: config_path.to_string(),
            config_file_content: config_content.to_string(),
            action: rpc_client::ConfigFileAction::Sync as i32,
        };

        let response = client.sync_config(request).await?;
        let resp = response.into_inner();
        
        if !resp.success {
            return Err(format!("配置同步失败: {}", resp.message).into());
        }

        Ok(())
    }

    /// 向单个Agent执行命令
    async fn execute_command_on_agent(
        &self,
        agent_address: &str,
        command: &str,
    ) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
        let mut client = rpc_client::config_monitor_a_client::ConfigMonitorAClient::connect(
            format!("http://{}", agent_address)
        ).await?;

        let request = rpc_client::ExecuteCommandRequest {
            command: command.to_string(),
            timeout: 30, // 30秒超时
        };

        let response = client.execute_command(request).await?;
        let resp = response.into_inner();
        
        if !resp.success {
            return Err(format!("命令执行失败: {}", resp.error).into());
        }

        Ok(resp.output)
    }

    fn parse_audit_log(request: &Request<rpc_server::ReportExceptionRequest>) -> String {
        let exception_message = request.get_ref().exception_message.clone();
        let parts: Vec<&str> = exception_message.split_whitespace().collect();
        let agent = request.get_ref().agent_address.clone();
        let mut key = "";
        let mut comm = "";
        let mut exe = "";
        let mut pid = "";
        let mut user = "";

        for part in parts {
            if part.starts_with("key=") {
                key = part
                    .split("key=\"CM_")
                    .collect::<Vec<&str>>()
                    .get(1)
                    .unwrap()
                    .split("\"")
                    .collect::<Vec<&str>>()
                    .get(0)
                    .unwrap();
            } else if part.starts_with("comm=") {
                comm = part
                    .split("comm=")
                    .collect::<Vec<&str>>()
                    .get(1)
                    .unwrap()
                    .trim_matches('"');
            } else if part.starts_with("exe=") {
                exe = part
                    .split("exe=")
                    .collect::<Vec<&str>>()
                    .get(1)
                    .unwrap()
                    .trim_matches('"');
                    
            } else if part.starts_with("pid=") {
                pid = part.split("pid=").collect::<Vec<&str>>().get(1).unwrap();
            } else if part.starts_with("AUID=") {
                user = part
                    .split("AUID=")
                    .collect::<Vec<&str>>()
                    .get(1)
                    .unwrap()
                    .trim_matches('"');
            }
        }

        format!(
            "!!! 发生了异常的配置文件修改: 主机{}中的配置文件{}被用户{}使用进程{}(可执行文件: {}, Pid: {})进行了修改, 已复原",
            agent,key, user, comm, exe, pid
        )
    }
}
